package ldh.im.fxgui.rpc.router;

import ldh.im.dto.base.OkResp;
import ldh.im.dto.business.base.DataChangeReq;
import ldh.im.exception.BusinessException;
import ldh.im.fxbase.util.BeanFactory;
import ldh.im.fxbase.util.ReflectionUtil;
import ldh.im.fxgui.rpc.service.DataSubTypeEnum;
import ldh.im.fxgui.rpc.service.DataTypeEnum;
import ldh.im.fxgui.util.UiUtil;
import ldh.rpc.util.JsonUtil;
import ldh.im.util.ParamCheckUtil;
import ldh.rpc.Rpc;
import ldh.rpc.RpcMapper;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import java.lang.reflect.Method;

@Rpc
public class DataChangeRouter {

    private static final Logger LOGGER = LoggerFactory.getLogger(DataChangeRouter.class);

    @RpcMapper(path="serverRedirectDataChange", asynHandle = true)
    public OkResp dataChange(DataChangeReq changeDataReq) {
        LOGGER.info("收到服务端数据变更信息, receive data change: {}", JsonUtil.toJson(changeDataReq));
        ParamCheckUtil.checkNotNull(changeDataReq.getKey(), "DataChangeReq", "key");
        ParamCheckUtil.checkNotNull(changeDataReq.getType(), "DataChangeReq", "type");
        ParamCheckUtil.checkNotNull(changeDataReq.getSubType(), "DataChangeReq", "subType");
        ParamCheckUtil.checkNotNull(changeDataReq.getValue(), "DataChangeReq", "value");
        String userId = UiUtil.getLoginImUser().getUserId();
        Object data = doBusiness(userId, changeDataReq);
        OkResp okResp = new OkResp(changeDataReq.getLocalSeq());
        return okResp;
    }

    private Object doBusiness(String userId, DataChangeReq changeDataReq) {
        try {
            DataTypeEnum dataTypeEnum = DataTypeEnum.wrap(changeDataReq.getType());
            Object changeDataService = BeanFactory.getInstance().getBean(dataTypeEnum.getHandleService());

            DataSubTypeEnum dataSubTypeEnum = dataTypeEnum.wrap(changeDataReq.getSubType());
            String methodName = dataSubTypeEnum.getMethodName();
            Object value = invoke(changeDataService, methodName, userId, changeDataReq);
            return value;
        } catch (Exception e) {
            throw new BusinessException("业务处理失败");
        }
    }

    private Object invoke(Object handleService, String methodName, String userId, DataChangeReq changeDataReq) throws Exception {
        Method method = ReflectionUtil.getMethod(handleService.getClass(), methodName, new Class[] {String.class, String.class, String.class});
        Object value = method.invoke(handleService, new Object[]{userId, changeDataReq.getKey(), changeDataReq.getValue()});
        return value;
    }
}
